1598F - RBS - CodeForces Solution


binary search bitmasks brute force data structures dp *2400

Please click on ads to support us..

C++ Code:

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx,avx2,sse,sse2")

#define mp make_pair
#define sz(x) (int)((x).size())
#define all(x) (x).begin(),(x).end()
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define eb emplace_back

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
	enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef HOME
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
	ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
	*this << "[";
	for (auto it = d.b; it != d.e; ++it)
		*this << ", " + 2 * (it == d.b) << *it;
	ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

const int DIM = 20;
const int MAX = 400'005;

char str[DIM][MAX];
int dp[1 << DIM][2], sum[1 << DIM], mnm[DIM];
int len[DIM], cnt[DIM], val[DIM][MAX * 2];

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
#ifdef HOME
	freopen("test.in", "r", stdin);
	freopen("test.out", "w", stdout);
#endif
	int n; cin >> n;
	for (int i = 0; i < n; ++i) {
		cin >> (str[i] + 1);
		int l = strlen(str[i] + 1);
		len[i] = l;
		int s = 0;
		for (int j = 1; j <= l; ++j) {
			s += (str[i][j] == '(' ? 1 : -1);
			debug() << imie(s);
			if (mnm[i] > s) {
				mnm[i] = s;
				cnt[i] = 1;
			} else if (mnm[i] == s) {
				++cnt[i];
			}
			if (mnm[i] == s)
				++val[i][s + l];
		}
		sum[1 << i] = s;
	}
	memset(dp, -0x3f, sizeof(dp));
	dp[0][true] = 0;
	for (int msk = 1; msk < (1 << n); ++msk) {
		int bb = (msk & -msk);
		sum[msk] = sum[msk ^ bb] + sum[bb];
		for (int b = 0; b < n; ++b) {
			if (!(msk & (1 << b)))
				continue;
			int axm = (msk ^ (1 << b));

			if (dp[axm][true] < 0) 
				continue;
			
			if (sum[axm] + mnm[b] < 0) {
				if (sum[axm] <= len[b])
					dp[msk][false] = max(dp[msk][false], dp[axm][true] + val[b][-sum[axm] + len[b]]);
				else
					dp[msk][false] = max(dp[msk][false], dp[axm][true]);
			} else {
				if (sum[axm] + mnm[b] == 0) 
					dp[msk][true] = max(dp[msk][true], dp[axm][true] + cnt[b]);
				else 
					dp[msk][true] = max(dp[msk][true], dp[axm][true]);
			}
		}
	}
	debug() << range(cnt, cnt + n);
	debug() << range(mnm, mnm + n);
	int ans = 0;
	for (int msk = 1; msk < (1 << n); ++msk)
		ans = max(ans, max(dp[msk][true], dp[msk][false]));
	cout << ans;
	return 0;
}


Comments

Submit
0 Comments
More Questions

1553D - Backspace
1670D - Very Suspicious
1141B - Maximal Continuous Rest
1341A - Nastya and Rice
1133A - Middle of the Contest
385A - Bear and Raspberry
1311B - WeirdSort
1713F - Lost Array
236B - Easy Number Challenge
275A - Lights Out
147A - Punctuation
253A - Boys and Girls
1327E - Count The Blocks
984A - Game
12B - Correct Solution
1355B - Young Explorers
485A - Factory
628A - Tennis Tournament
1436B - Prime Square
1707B - Difference Array
1422C - Bargain
1611F - ATM and Students
660A - Co-prime Array
1692F - 3SUM
1470A - Strange Birthday Party
190D - Non-Secret Cypher
1721B - Deadly Laser
1721C - Min-Max Array Transformation
1721A - Image
1180C - Valeriy and Deque